#!/usr/bin/perl

package MozComics::MySQL;

use MozComics::Utils;
our @ISA = qw(MozComics::Utils);

use strict;
use warnings;
use DBI;
use DBD::mysql;
use MozComics::MySQL::DBH;


my $dbh; # database connection


sub new {
	my $errorHeader = 'MozComics->new';
	my $className = shift(@_) or die "$errorHeader: class name not passed";
	my $guid = shift(@_) or die "$errorHeader: guid not passed";
	my $maxNew = (shift(@_) or 1);

	# create object
	my $self = {};
	bless($self, $className);

	# initialize database connection if it hasn't been initialized yet
	if(not defined $dbh) {
		$dbh = MozComics::MySQL::DBH->get();
	}

	# use passed guid to get comic
	my $query = qq/SELECT comic,name,updated FROM comic WHERE guid=?/;
	my $sth = $dbh->prepare($query);
	$sth->execute(($guid));
	my $comic = $sth->fetchrow_hashref or die "$errorHeader: guid not in db";

	$errorHeader .= " ($comic->{name})";
	my @stripQueue = ();
	my $updated = time;

	# check to make sure the new updated time is greater than the stored one
	if($updated <= $comic->{updated}) {
		die "$errorHeader: comic was updated in the future?";
	}

	$self->{guid} = $guid;
	$self->{comic} = $comic->{comic};
	$self->{name} = $comic->{name};
	$self->{maxNew} = $maxNew;
	$self->{stripQueue} = \@stripQueue;
	$self->{updated} = $updated;
	$self->{commited} = 0;

	return $self;
}


sub getLastStrip {
	my $self = shift(@_);
	my $errorHeader = "MozComics->getLastStrip ($self->{name})";

	my $joinedColumns = join(',', MozComics::Utils::ALL_COLUMNS);
	my $query = "SELECT $joinedColumns FROM strip WHERE comic=? AND action != 1 ".
	            "ORDER BY strip DESC LIMIT 1";
	my $sth = $dbh->prepare($query);
	$sth->execute(($self->{comic}));
	return ($sth->fetchrow_hashref or die "$errorHeader: no strips found");
}


sub getStripCount {
	my $self = shift(@_);
	my $errorHeader = "MozComics->getLastStrip ($self->{name})";
	my $conditions = (shift(@_) or {});

	my @conditionStrings = ('comic = ?');
	my @parameters = ($self->{comic});

	# only consider valid conditions
	for my $col (MozComics::Utils::MANUAL_COLUMNS) {
		if(defined $conditions->{$col}) {
			push @conditionStrings, "$col = ?";
			push @parameters, $conditions->{$col};
		}
	}
	
	my $fullConditionString = join(' AND ', @conditionStrings);
	my $query = qq/SELECT COUNT(*) FROM strip WHERE $fullConditionString/;

	my $sth = $dbh->prepare($query);
	$sth->execute(@parameters) or die "$errorHeader: execution failed ($query)";
	my @row = $sth->fetchrow_array or die "$errorHeader: fetch failed ($query)";
	return $row[0];	
}


sub commit {
	my $self = shift(@_);
	my $errorHeader = "MozComics->commit ($self->{name})";

	if($self->{committed}) {
		die "$errorHeader: can not commit more than once";
	}
	$self->{committed} = 1;

	my @stripQueue = @{$self->{stripQueue}};
	my $queueSize = @stripQueue;
	if($queueSize == 0) {
		return;
	}

	my $comic = $self->{comic};
	my $updated = $self->{updated};

	my @parameters;
	for my $strip (@stripQueue) {
		push(@parameters, ($comic, $updated));
		for my $col (MozComics::Utils::MANUAL_COLUMNS) {
			push(@parameters, $strip->{$col});
		}
	}

	# generate and prepare queries
	my $numColumns = MozComics::Utils::ALL_COLUMNS;
	my $rowParameters = '?,' x $numColumns;
	chop $rowParameters;
	my $allParameters = "($rowParameters)," x $queueSize;
	chop $allParameters;

	my $joinedColumns = join(',', MozComics::Utils::ALL_COLUMNS);
	my $insertQuery = qq/INSERT INTO strip($joinedColumns) VALUES $allParameters/;
	my $preparedInsertQuery = $dbh->prepare($insertQuery);

	my $updateQuery = q/UPDATE comic SET updated = ? WHERE comic = ?/;
	my $preparedUpdateQuery = $dbh->prepare($updateQuery);

	# execute queries
	$preparedInsertQuery->execute(@parameters)
	    or die "$errorHeader: inserting rows failed";
	$preparedUpdateQuery->execute(($updated, $comic))
	    or die "$errorHeader: updating comic failed";
}

1;

__END__

=head1 NAME

MozComics::MySQL - A MozComics comic object with MySQL back-end

=head1 SYNOPSIS

	use MozComics::MySQL;

	$comic = MozComics::MySQL->new($guid);
	$comic = MozComics::MySQL->new($guid, $maxNewStrips);

	# documentation of comic methods is located in MozComics::Utils

=head1 DESCRIPTION

MozComics::MySQL is a class representing a MozComics comic with a MySQL back-end. The class is used to easily scrape and add new strips to a comic.

For a JSON back-end, use MozComics::JSON.

=head2 Set-Up

The MySQL back-end uses two tables: comic and strip. More information about what these tables contain can be found at L<http://mozcomics.com/support/comic_data>.

=head2 Methods

Documentation located in MozComics::Utils.

=head1 AUTHOR

Ben Parr <bparr@bparr.com>

=head1 COPYRIGHT

Copyright (c) 2009-2010 Ben Parr. All code licensed under the The MIT License (L<http://www.opensource.org/licenses/mit-license.php>)

=head1 SEE ALSO

L<MozComics::Utils>, L<MozComics::JSON>

=cut

